데이터 과학을 위한 파이썬

Intro

파이썬으로 데이터를 다루기 위해 가장 기본적으로 알아야 하는 것이 데이터의 형태입니다. 데이터는 숫자, 문자, 배열, 집합, 순서쌍 등 다양한 형태를 가질 수 있습니다. 파이썬에는 몇 가지 기본적인 자료형들이 정의되어 있으며, 각각의 자료형마다 다른 연산과 조작을 할 수 있습니다. 이번 장의 목표는 내가 다루는 데이터가 어떤 형태인지를 알고, 자료형에 맞는 연산과 조작을 할 수 있는 능력을 키우는 것입니다.

기본적인 파이썬 자료형

다음은 파이썬에서 사용되는 기본적인 자료형들의 예시입니다. 자세한 내용은 앞으로 차근차근 다룰 예정이니 눈으로만 봐두시면 됩니다.

  • >>> 표시가 붙은 부분은 파이썬 코드입니다.
  • # 표시가 붙은 부분은 코드에 대한 주석으로, 실제 실행되는 파이썬 코드가 아닙니다.

기본적인 함수와 연산자

다음은 이번 장에서 사용할 간단한 함수 및 연산자들입니다. 비교연산자 ==와 할당연산자 =의 차이에 유의하시기 바랍니다. 할당연산자 =는 두 대상이 같은지 비교하는 연산자가 아니라, 변수에 값을 할당하는 할당연산자입니다. 즉 a=5은 “a는 5와 같다”가 아니라, “a에 5를 할당하라”는 명령입니다!

함수/연산자 기능 예시 코드 실행결과
print 대상을 출력 print("Hello world!") Hello world!
type 대상의 자료형을 반환 type(5) int
len 대상의 길이를 반환 len("abc") 3
== “두 대상이 같다”를 판단 'Python'=='R' False
!= “두 대상이 같지 않다”를 판단 'Python'!='R' True
= 왼쪽 변수에 오른쪽 값을 할당 a=5

1. 숫자

1.1. 정수와 소수

파이썬의 숫자는 정수소수로 나뉘며, 각각 intfloat으로 표기합니다. 아래는 정수 2와 소수 3.14의 자료형을 확인하는 코드와 결과입니다.

1.2. 자료형의 변환

int 함수는 숫자나 문자열을 정수 자료형으로 바꿔주고, float 함수는 숫자나 문자열을 소수 자료형으로 바꿔줍니다. 소수점을 가진 숫자 혹은 문자열을 정수로 변환하면 소수점 아래는 버림됩니다.

함수 기능 예시 코드 결과
int 대상을 정수로 변환 int(4.8) 4
float 대상을 소수로 변환 float("3") 3.0

1.2 파이썬으로 계산하기

숫자들 간에는 정수와 소수 구분 없이 다음의 연산이 가능합니다. 사칙연산과 제곱을 제외한 연산자들은 사용하는 빈도가 많지 않으니, 이런 연산이 있다고만 알아두시면 됩니다.

연산자 기능 예시 코드 실행결과 결과의 자료형
a + b 덧셈 1+1 2 int
a - b 뺄셈 3-2.5 0.5 float
a * b 곱셉 2*4.5 9.0 float
a / b 나눗셈 0.9/0.3 3.0 float
a ** b a의 b제곱 5**2 25 int
a // b a를 b로 나눌 때의 몫 8//3 2 int
a % b a를 b로 나눌 때의 나머지 8%3 2 int

2. 문자열

2.1. Hello World

문자열은 말 그대로 문자들의 나열을 의미하며, str로 표기합니다. 작은 따옴표 '', 혹은 큰 따옴표 "" 를 사용해서 만들 수 있습니다. 둘 중 무엇을 사용하든 상관은 없습니다. 프로그래밍 언어를 배울 때는 "Hello World"를 출력해보는 것이 관례입니다. 다같이 인사해보세요!

예제 2-1. 다음 코드의 실행 결과가 True일지 False일지 판단하세요

풀이

365는 숫자이고, "365"는 따옴표로 둘러싸여 있으므로 문자열입니다. 문자열 "365"와 숫자 365가 같은지 테스트해보면, 양쪽의 자료형이 다르기 때문에 False가 반환됩니다.

2.2. 자료형의 변환

str 함수를 사용해서 숫자를 문자열로 바꿔줄 수 있습니다.

2.3. 문자열 연산자

innot in 연산은 문자열 뿐 아니라 리스트 등의 자료형에서도 자주 쓰이는 연산이니 알아두면 좋습니다.

연산자 기능 예시 코드 결과
a + b a 문자열과 b 문자열을 합침 "A" + "B" "AB"
a * b a 문자열을 b 회 반복 "A" * 3 "AAA"
a in b “a가 b에 포함된다”를 판단 "A" in "ABCDEFG" True
a not in b “a가 b에 포함되지 않는다”를 판단 "A" not in "ABCDEFG" False

예제 2-2. 다음 코드의 실행 결과를 판단하세요(True/False/Error)

풀이

"DatascienceLab""Data"라는 문자열을 포함하기 때문에 첫 줄의 실행 결과는 False입니다. 1은 숫자이고, "123"은 문자열이기 때문에 둘째 줄의 결과는 에러입니다. 숫자와 문자열 간에는 innot in이라는 관계 연산이 정의되지 않습니다.

2.4. 인덱싱 & 슬라이싱

문자열은 문자를 순서대로 나열한 데이터입니다.문자열을 구성하는 하나하나의 문자에 순서대로 번호를 매길 수 있으며, 이 번호를 인덱스라고 부릅니다. 아래 그림은 "Hello World"라는 문자열에 앞쪽부터 번호를 매긴 결과입니다. 파이썬의 인덱스는 0부터 시작하기 때문에, 가장 먼저 나온 문자인 "H"의 인덱스는 0이 됩니다. 그 이후 순차적으로 1, 2, ... 10 까지의 번호가 매겨졌습니다. 공백 역시 문자열에 포함된다는 사실을 유의해주세요! 파이썬의 인덱스는 뒤에서부터 부여할 수도 있습니다. 인덱스를 뒤에서부터 매기면 -1, -2, ... 와 같이 음수가 됩니다.

문자열 H e l l o w o r l d
인덱스 0 1 2 3 4 5 6 7 8 9 10
-인덱스 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1

인덱싱

문자열에 부여된 인덱스를 통해서 개별 문자를 뽑아낼 수 있고, 이것을 인덱싱이라고 합니다. 비유하면, 여러분과 파이썬이 다음과 같은 대화를 한다고 생각하시면 됩니다.

You: “Hello world”의 0번 문자를 찾아줘!

Python: “Hello world”의 0번 문자는 “H” 입니다.

그렇다면 "Hello world"의 0번 문자를 찾아줘!’라는 명령을 어떻게 파이썬에 전달할 수 있을까요? 문자열 바로 뒤에 대괄호[]를 적고, 대괄호 안에 원하는 인덱스 숫자를 넣어주면 됩니다. 실제 파이썬 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

문자열 인덱스 예시 코드 결과
"Python" 0 "Python"[0] 'P'
"DataScience Lab" 12 "DataScience Lab"[12] 'L'
"010-5782-xxxx" 7 "010-5782-xxxx"[7] '2'
"You need Python." -1 "You need Python."[-1] '.'

예제 2-3. 다음 코드의 실행 결과를 판단하세요

풀이

"Python is too slow"라는 문자열을 mystring이라는 변수에 할당했습니다. 따라서 mystring[-2]'mystring[4]'는 모두 'o'입니다. 두 값이 같으므로 != 연산의 결과는 False입니다.

슬라이싱

슬라이싱은 말 그대로 문자열의 일정 구간을 잘라내는 조작입니다. 일정 구간에 걸쳐서 인덱싱을 실행한다고 생각하시면 편합니다. 역시 대화로 표현하면 다음과 같습니다.

You: “Hello world”의 0번부터 4번까지의 문자를 찾아줘!

Python: “Hello world”의 0번부터 4번까지 문자는 “Hello” 입니다.

슬라이싱을 할 때는, [a:b]와 같이 대괄호 안에 구간을 입력해주면 됩니다. 구간을 입력할 때는 주의사항이 있습니다. 예시와 함께 보겠습니다.

[0:4]의 구간을 입력했으므로 0, 1, 2, 3, 4번 문자가 출력되어야 할 것 같은데, 이상하게 'Hell'까지만 출력되었습니다. 이는 구간 [a:b]가 a는 포함하지만, b는 포함하지 않기 때문입니다. 즉 0번부터 4번까지를 슬라이싱 하려면 구간을 [0:5]와 같이 입력해야 합니다.

슬라이싱의 구간 표현법을 정리하면 다음과 같습니다. 콜론 : 양쪽의 숫자를 생략하면 끝까지 슬라이싱합니다.

구간 설명 예시 코드 실행 결과
[a:b] a번 문자부터 b번 문자 직전까지 슬라이싱 'www.naver.com'[4:9] 'naver'
[:] 문자열의 전 구간을 슬라이싱 "Super Awesome Code"[:] 'Super Awesome Code'
[a:] a번 문자부터 끝까지 슬라이싱 "Avengers: Endgame"[-7:] 'Endgame'
[:b] 처음부터 b번 문자 직전까지 슬라이싱 "서울특별시 서대문구"[:5] '서울특별시'

예제 2-4. 다음 문자열에서 이메일 주소를 뽑아내세요

풀이

이메일 주소가 가장 뒤에 위치하므로 인덱스를 뒤쪽부터 세는게 편해 보입니다. len 함수를 활용하여 문자열의 길이를 파악하였습니다. 음수 인덱스를 활용하여 -21번 인덱스부터 끝까지 슬라이싱하면 이메일 주소를 뽑아낼 수 있습니다.

2.5. 문자열의 메소드

메소드는 일종의 함수이며, 대상 뒤에 점 . 을 찍고 사용할 수 있습니다. 함수이므로 반드시 () 와 함께 사용합니다.

메소드 기능
s.strip() s 문자열 양쪽의 공백을 제거
s.replace(a,b) s 문자열 내의 a 문자열을 b 문자열로 교체
a.split(b) b 문자를 기준으로 a 문자열을 쪼갬
a.join(b) b 문자열 사이사이에 a 문자열을 삽입

strip

strip 메소드는 문자열 양쪽의 공백을 모두 제거합니다. 원하는 문자열 뒤에 점을 찍어서 "문자열".strip()과 같이 적어주면 됩니다. 문자열 " Hello world "는 양쪽에 공백이 있고, 가운데에도 한 칸의 공백이 있습니다. strip 메소드를 활용하면 가운데의 띄어쓰기는 남겨두고 양 쪽의 공백만을 제거할 수 있습니다.

사실 s.strip()은 s를 실제로 변화시키는 것이 아니라, 변화한 상태를 일시적으로 보여주는 것입니다. s를 출력해보면 양쪽의 공백이 그대로 남아있습니다. 공백을 제거한 결과를 s에 저장하고 싶다면, s = s.strip()과 같이 다시 할당을 해주어야 합니다. = 는 수학적인 의미의 등호가 아니라, 할당을 뜻하는 연산자이므로, s = s.strip()이라는 코드는 “s.strip()을 실행하고 이 결과를 s에 할당하라”는 의미입니다. s 와 s.strip() 이 같다는 의미가 아닙니다!

탭을 의미하는 \t 문자열과 개행을 의미하는 \n 문자열 역시 공백으로 인식됩니다. 아래 예시 코드를 보면, strip 메소드가 \t\n을 공백으로 인식하여 삭제하였음을 확인할 수 있습니다.

replace

replace 메소드는 문자열 내의 특정 문자를 다른 문자로 모두 교체합니다. s.replace(a,b)와 같이 적어주면 s 문자열 내의 a 문자열을 모두 b 문자열로 교체합니다. 아래는 문자열 "You need Python" 에서 "Python""R"로 바꾸어준 예제입니다. 역시 s.replace("Python","R")를 실행하는것만으로는 변수에 할당된 값이 변화하지 않습니다.

예제 2-5. a를 b와 같은 문자열로 변형하고 결과를 검증하세요. 단, 문자열 조작하는 과정에는 한 줄의 코드만 사용할 수 있습니다.

풀이

1) 문자열의 양쪽 공백을 제거해준 후, 2) 중간중간의 공백을 |로 교체해주면 문제를 해결할 수 있습니다. 얼핏 보면 다음과 같이 두 줄의 코드가 필요할 것 같습니다. 먼저 양쪽의 공백을 지운 결과를 tmp라는 임시 변수에 저장합니다. 이후 tmp에서 공백을 |로 교체하고 이 결과를 result라는 변수에 최종적으로 저장합니다. bresult를 비교해보면 두 값이 같다는 사실을 알 수 있습니다.

위의 코드가 틀린 것은 아니지만, tmp라는 임시 변수를 사용하지 않고 코드를 더 간소화할 수 있습니다. 아래 풀이에서는 메소드 체이닝, 즉 메소드를 연결하는 코드를 통해서 두 번의 조작을 한 줄의 코드로 끝냈습니다. a.strip()의 결과는 양쪽 공백이 제거된 "C GO Jave Python PHP" 입니다. 따라서 a.strip().replace(" ","|")는 결국 "C GO Jave Python PHP".replace(" ","|")와 같습니다.

split

split 메소드는 특정 문자를 기준으로 문자열을 쪼개어 리스트를 반환합니다. s.split(a)와 같이 적어주면 a 문자열을 기준으로 s 문자열을 쪼개어 리스트를 반환합니다. 아무런 문자도 주어지지 않는다면 공백을 기준으로 문자열을 쪼갭니다.

>>> s = "one/two/three/four"
>>> s.split("/") # "/" 를 기준으로 문자열을 쪼갬 > 이 결과를 리스트로 반환
['one', 'two', 'three', 'four']

예제 2-6. 다음 코드의 실행 결과를 예상해보세요

풀이

문자열에서 @.으로 교체해준 후, .을 기준으로 나누었으므로 결과는 다음과 같습니다.

join

join 메소드는 문자열 사이사이에 다른 문자를 삽입합니다. a.join(b)와 같이 적어주면 b 문자열 사이사이에 a 문자열을 삽입한니다. join 메소드는 문자열보다는 리스트에 대해 사용하는 경우가 많습니다

2.6. 문자열 포매팅

문자열 포매팅은 문자열 안에 변수를 포함하는 기능입니다. 유사한 패턴의 문자열에서 특정 부분만 변형해서 사용해야 하는 경우, 문자열 포매팅이 유용합니다. 여기에서는 f 포매팅에 대해서 배워보겠습니다. f 포매팅을 사용할 때는 문자열을 감싼 따옴표 앞에 f를 적어줍니다. 이후 변수를 사용할 위치에 중괄호{}를 쓰고, 중괄호 안에 원하는 변수를 입력해주면 됩니다.

3. 불리언

3.1. 불리언 자료형

불리언은 참/거짓을 나타내는 자료형이며, 각각 True, False로 씁니다. 크게 주의할 것은 없고, 파이썬에서 0False를 의미한다는 것은 알고 넘어가면 좋습니다.

3.2. 논리 연산자

불리언 자료형에서 가장 중요한 것은 논리 연산입니다. 크게 복잡한 것은 없지만 조건문에서 자주 활용되는 연산이므로 알아두시면 좋습니다.

연산자 기능 예시 코드 실행 결과
a & b “a와 b가 모두 참이다”를 판단 True & True True
a and b “a와 b가 모두 참이다”를 판단 True and False False
a|b “a, b 중 최소한 하나가 참이다”를 판단 True | False True
a or b “a, b 중 최소한 하나가 참이다”를 판단 False or False False

예제 3.1. 다음 연산의 실행 결과를 판단하세요

풀이

첫 줄은 (10 < 10)(10 > 10) 이라는 두 개의 명제로 이루어져 있습니다. 두 명제 모두 거짓이므로 False or False가 되고, 결과는 False입니다. 둘째 줄은 ("Python" != "R")("Life"=="short") 라는 두 개의 명제로 이루어져 있습니다. 첫 명제는 참이지만 둘째 명제는 거짓이므로 True and False가 되고, 결과는 False입니다.

3.3. any, all

any 함수와 all 함수는 파이썬의 컬렉션들에 적용할 수 있는 함수입니다. 컬렉션이란 여러 요소들을 모아놓은 자료형으로, 뒤에서 배울 리스트가 대표적인 파이썬의 컬렉션입니다.

함수 기능
any 대상이 True를 하나라도 포함하면 True, 아니면 False를 반환
all 대상이 True만을 포함하면 True, 아니면 False를 반환

4. 변수와 함수

4.1. 변수

변수는 정보를 담는 공간입니다. 우리가 x=3 이라는 할당을 시행하면 컴퓨터는 메모리 어딘가에 3이라는 정보를 기록하고, x라는 라벨을 붙입니다. 이후 코드에서 x라는 변수를 사용하면, 컴퓨터는 x라는 라벨이 붙은 정보를 찾아 계산에 사용하게 되는 것입니다. 변수가 메모리 어디에 저장되어 있는지는 id 함수를 사용하면 알 수 있습니다.

  • 변수는 숫자로 시작할 수 없다
  • 파이썬 예약어(키워드)는 변수로 사용할 수 없다
  • 하나의 변수명에는 하나의 객체가 대응한다

4.2. 함수

함수의 구조

위키백과

위키백과

우리가 흔히 알고 있는 함수는 y = f(x)와 같은 형태입니다. x라는 입력이 들어가면, f(x)라는 함수값이 출력됩니다. 파이썬의 함수 역시 이와 유사하게 작동합니다. 파이썬에서는 x를 인자(argument) 또는 매개변수(parameter)라고 부르고, y를 반환(return)이라고 부릅니다.

파이썬의 함수는 def 문을 통해 만들 수 있으며, def 문의 구조를 일반화하면 위와 같습니다. def 다음 함수명을 적고, 괄호 안에 필요한 매개변수들을 적어줍니다. 이후 다음 줄로 넘어가 들여쓰기(스페이스 네 개)된 상태에서 계산을 진행하면 됩니다. 대부분의 편집기에서는 자동으로 들여쓰기를 적용해줍니다. 계산이 끝나면 return 절에 반환할 결과물을 적어줍니다.

add 함수는 xy라는 두 개의 인자를 받아서 더하고, 이 결과를 반환합니다. 함수를 사용할 때는 함수 이름을 적고, 등호 =를 사용해서 필요한 인자들을 전달해줍니다. 인자를 순서대로 전달했다면, 매개변수명을 생략할 수 있습니다.

함수 안에서 사용되는 변수들은 지역 변수(local variable)로, 함수 안에서만 유효합니다. 즉 함수 밖에서는 함수 안의 변수들에 접근할 수 없습니다. 예를 들어 우리가 만든 add 함수에 x=4, y=5를 전달하고 실행하면 함수 안에서는 다음과 같은 일이 일어날 것입니다.

하지만 함수를 실행한 후 result를 출력하면 변수 result가 선언되지 않았다는 에러가 발생합니다. 함수 안에서 사용되는 변수는 지역 변수(local variables)로, 함수 안에서만 유효하기 때문입니다. 따라서 함수의 실행 결과를 저장하려면 이를 별도의 변수에 할당해주어야 합니다.

예제 4-1. 이메일 문자열이 gmail 주소이면 True, 아니면 False를 반환하는 함수를 작성하세요. 다음과 같이 작동하면 됩니다.

풀이

주어진 문자열에 "@gmail.com"이 포함되는지를 판단하면 되는 문제입니다. 함수의 이름을 my_function으로 정하고, address라는 매개변수로 문자열을 받았습니다. 이제부터 address는 어떤 문자열을 가리키는 변수라고 상상하면서 코딩을 해주면 됩니다. in 연산을 통해 address"@gmail.com"이 포함되는지 판단할 수 있습니다. 이 결과를 result라는 변수에 저장하고, return result로 결과를 반환합니다.

연산이 간단할 때에는 다음과 같이 적는 것도 가능합니다. 한 줄의 코드로 끝나는 연산이기 때문에 별도의 변수를 사용하지 않고 즉시 반환하였습니다.

인자와 반환

사실 파이썬의 함수는 일반적인 함수와 달리 x와 y가 없이도 작동할 수 있습니다. 즉 파이썬의 함수는 다음과 같은 네 가지 경우로 구분할 수 있습니다.

  1. 매개변수와 반환이 모두 있는 함수
  2. 매개변수가 없고 반환이 있는 함수
  3. 매개변수가 있고 반환이 없는 함수
  4. 매개변수와 반환이 모두 없는 함수

예제 4-2. 다음 함수들이 1,2,3,4 중 어디에 해당하는지 판단하세요.

풀이

  1. x, y 두 개의 매개변수가 있지만 return이 없으므로 3에 해당
  2. 매개변수가 없고 return이 없으므로 4에 해당
  3. 매개변수가 없고 return이 있으므로 2에 해당
  4. x, y 두 개의 매개변수가 있고 return이 있으므로 1에 해당

lambda 함수

지금까지는 def 문을 통해서 함수를 만드는 방법을 배웠습니다. 하지만 한 줄 정도의 간단한 함수를 만들 때는 lambda 문을 사용하는 것이 편리합니다. lambda 뒤에 괄호를 사용하지 않고 매개변수들을 나열해준 후, 콜론 다음에 계산식을 적어주면 됩니다. lambda 문에서는 return을 사용하지 않으며, 콜론 이후 코드의 실행 결과가 즉시 반환됩니다. lambda 문을 변수에 할당하면 해당 변수명으로 함수가 생성됩니다.

lambda 문의 구조를 일반화하면 다음과 같습니다.

5. 리스트

5.1. 리스트 생성

리스트는 [요소1, 요소2, 요소3, ...]과 같이 여러 요소들을 묶어놓은 자료형입니다. 대괄호 혹은 list 함수를 사용해서 리스트를 생성할 수 있습니다. 각 요소들은 쉼표 ,로 구분합니다. 리스트는 거의 모든 자료형을 요소로 가질 수 있으며, 요소들의 자료형이 모두 같을 필요도 없습니다. 다음은 모두 리스트의 예시입니다.

5.2. 리스트 연산자

연산자 기능 예시 코드 결과
+ 두 리스트를 합침 [1,2,3] + [4,5,6] [1,2,3,4,5,6]
* 리스트의 요소들을 반복 [1,2,3]*2 [1,2,3,1,2,3]
a in b “a 요소가 b 리스트 안에 포함된다”를 판단 1 in [1,2,3] True
a not in b “a 요소가 b 리스트 안에 포함되지 않는다”를 판단 1 not in [1,2,3] False

in 연산자와 not in 연산자는 기억하고 넘어가시기 바랍니다.

예제 5-1. 다음 코드의 실행 결과를 판단하세요(True/False)

풀이

[1,2,3]의 요소는 1, 2, 3 이므로 [1,2,3][1,2,3]의 요소가 아닙니다. 따라서 첫 줄의 결과는 True입니다. [[1,2,3]]의 요소는 [1,2,3]뿐이므로 결과는 False입니다.

5.3. 리스트 인덱싱 & 슬라이싱

리스트는 요소들의 순차적인 배열입니다. 따라서 문자열과 마찬가지로, 각각의 요소들에 번호를 매길 수 있습니다. 번호를 매기는 방식 역시 문자열과 동일합니다. 즉 앞에서부터 0, 1, 2 … 순으로 인덱스가 붙고, 뒤에서부터 -1,-2,-3 … 순으로 인덱스가 붙습니다. 예를 들면 다음과 같습니다.

요소 “Life” “is” “short” “you” “need” “Python”
인덱스 0 1 2 3 4 5
인덱스 -6 -5 -4 -3 -2 -1

인덱싱

문자열의 인덱싱과 슬라이싱에 익숙해졌다면, 리스트의 인덱싱과 슬라이싱 역시 어렵지 않을 겁니다. 리스트의 인덱싱 역시 문자열과 마찬가지로 대괄호 []를 사용합니다.

리스트 인덱스 예시 코드 결과
[0.25, 0.5, 0.75, 1.0] 1 [0.25, 0.5, 0.75, 1.0][1] 0.5
["You", "need", "Python"] -1 ["You", "need", "Python"][-1] 'Python'
[[1,2,3],[4,5,6],[7,8,9]] 2 [[1,2,3],[4,5,6],[7,8,9]][2] [7,8,9]

인덱싱을 사용하여 개별 요소를 추출하였다면, 해당 요소에 대해 다시 조작을 가하는 것도 가능합니다. 아래는 리스트에서 개별 요소를 추출한 후, 해당 요소에 대해 다시 인덱싱/슬라이싱을 적용한 예제입니다.

예제 5-2. 다음 리스트에서 “Wally”를 추출하세요.

풀이

“Wally”는 두 번째 서브리스트의 두 번째 요소입니다. 따라서 다음과 같이 두 번의 인덱싱으로 손쉽게 월리를 찾아낼 수 있습니다.

예제 5-3. 다음 주소에서 문자열 인덱싱을 사용하지 않고 동을 추출하세요.

풀이

주어진 문자열은 띄어쓰기 기준으로 스플릿할 수 있습니다. 스플릿을 실행하면 각 어절이 리스트의 요소로 들어갈 것이고, “신촌동”은 리스트의 두 번째 요소가 될 것입니다. 이 결과를 코드로 정리해주면 됩니다.

슬라이싱

리스트 슬라이싱 역시 문자열 슬라이싱과 다르지 않습니다. 대괄호 안에 콜론을 써서 구간을 표현해주시면 됩니다.

이번에는 특정 요소들을 건너뛰는 슬라이싱을 배워보겠습니다. 예를 들어 리스트 안에서 홀수 인덱스를 가진 요소들만 추출할고 싶을 때, 이 방법을 활용할 수 있습니다. 기본적인 구간 표현법은 start:end:step과 같습니다. 이는 start부터 end까지 step만큼 이동하면서 가져오라는 의미입니다. step이 1이면 바로 다음 요소로 가는 것이므로 해당 구간의 모든 요소들을 가져올 것이고, step이 2이면 한 칸씩 건너뛰면서 요소들을 가져올 것입니다.

예제와 함께 보겠습니다. 첫 예제에서 사용한 구간 1:8:2는 1번 인덱스부터 8번 인덱스까지 2칸씩 진행하면서 요소들을 가져오라는 뜻입니다. 즉 따라서 1, 3, 5, 7번 인덱스에 해당하는 1, 3, 5, 7이 추출되었습니다. 두 번째 예제에서는 start와 end를 생략하여 리스트의 전 구간을 표현하였고, step은 2로 주었습니다. 따라서 0, 2, 4, 6, 8번 인덱스에 해당하는 0, 2, 4, 6, 8이 추출되었습니다.

5.4. 리스트 메소드

메소드 기능
a.append(b) 리스트 a에 요소 b를 추가함
a.index(b) 리스트 a에서 요소 b의 인덱스를 찾음

append

append 메소드는 특정 리스트에 요소를 추가하는 메소드입니다. 이 메소드는 리스트를 즉시 변형시키므로 주의해서 사용해야 합니다.a.append(b)를 실행하면 즉시 리스트에 요소가 추가되고, 다시 할당을 할 필요가 없습니다.

5.5. 리스트의 요소들에 함수 적용하기: map

map 함수는 리스트 내의 요소들에 일괄적으로 함수를 적용하는 함수입니다. 만약 리스트 안의 모든 요소들에 2를 곱하고 싶다면 어떻게 코드를 짜야 할까요? 리스트의 사칙연산은 숫자와 다르게 작동하므로, [1,2,3] * 2 와 같은 코드로는 원하는 결과를 얻을 수 없습니다. 이 때 map 함수를 사용하면 쉽게 해결이 가능합니다. map은 함수와 반복 가능한 객체 하나를 인자로 받습니다. 반복 가능한 객체는 리스트와 같이 각 요소에 차례대로 접근할 수 있는 객체를 말합니다.

>>> map(f, iterable)

아래 예시 코드를 보겠습니다. a는 리스트이고, f는 x라는 인자를 받아서 x의 제곱을 반환하는 함수입니다. map(f,a)는 a 리스트의 각 요소에 f 함수를 적용하는 코드입니다. 하지만 map(f,a)까지만 실행하면 계산이 실제로 실행되지는 않으며, 맵 객체라는 이상한 결과가 반환됩니다. 이 객체는 실제 계산을 실행하기 위해 대기중인 상태입니다. 실제 계산 결과를 반환받으려면 list로 다시 한 번 감싸주어야 합니다.

예제 5-4. address_list는 주소 문자열을 요소로 갖는 리스트입니다. address_list 각 요소들에서 시/도를 추출하여 리스트를 만드세요. 다음과 같은 결과를 얻으시면 됩니다.

풀이

1. 주소 문자열로부터 시도를 분리할 수 있는 패턴 찾기

  • 주어진 문자열들은 띄어쓰기를 기준으로 분리할 수 있고, 각 문자열의 첫 번째 어절이 시/도를 나타냅니다. 따라서 띄어쓰기를 기준으로 문자열을 스플릿한 후, 이렇게 생성된 리스트의 첫 요소를 추출하면 시/도를 추출할 수 있을 것입니다.

2. 1의 과정을 함수화하기

  • x라는 인자를 문자열로 생각하면, x.split(" “) 메소드를 활용해 x를 띄어쓰기 기준으로 분리 가능합니다. 이 결과는 하나의 리스트일 것이고, 리스트의 첫 번째 요소를 추출하기 위해서 [0]과 같이 인덱싱을 햊면 됩니다. 이 과정을 붙여 쓰면 x,split(” “)[0]이 되고, 이를 lambda문에 넣어서 함수화하는 과정을 my_function = lambda x: x.split(” ")[0] 과 같이 쓸 수 있습니다.

3. 리스트에 함수 적용하기

  • map을 활용해 함수를 적용하고 list()를 씌워서 결과를 출력하면 끝입니다!

6. 튜플

튜플은 순서쌍이며, 소괄호를 사용하여 만들 수 있습니다. 요소들의 순서가 있는 배열이라는 점에서 리스트와 거의 비슷하지만, 튜플은 요소를 수정할 수 없으며 요소들의 자료형이 모두 같아야 합니다. 자주 쓰는 자료형은 아니지만, 특징을 알아둘 필요가 있습니다.

7. 셋

7.1. 집합

셋은 집합이며, 중괄호{} 를 사용하거나 set 함수를 사용해서 만들 수 있습니다.

셋의 중요한 특징들은 다음과 같습니다.

  • 셋은 중복을 허용하지 않는다
  • 셋에는 순서가 없다
  • 합집합, 교집합, 차집합 등의 집합 연산이 가능하다

7.1. 집합으로 중복 제거하기

중복을 허용하지 않는다는 특징 때문에 집합은 중복을 제거하는 수단으로 활용되기도 합니다. 중복이 존재하는 리스트를 집합으로 만들었다가, 다시 리스트로 변환하는 과정을 통해서 리스트의 중복을 제거할 수 있습니다.

7.2. 집합 연산

집합 연산자는 1) 연산자를 통해서 실행하는 방법, 2) 메소드를 통해서 실행하는 방법이 있습니다. 어떤 방법을 사용해도 상관 없습니다.

합집합

합집합은 | 연산자 혹은 union 메소드를 활용합니다. 집합의 개수와 상관 없이 연산이 가능합니다.

교집합

교집합은 & 연산자 혹은 intersection 메소드를 활용합니다. 역시 집합의 개수와 상관 없이 연산이 가능합니다.

차집합

차집합은 - 연산자 혹은 difference 메소드를 활용합니다.

8. 딕셔너리

8.1. 딕셔너리 만들기

사전에서 ’people’을 찾으면 ’사람’이라는 뜻이 대응되고, ’science’를 찾으면 ’과학’이라는 뜻이 대응됩니다. 파이썬의 딕셔너리 역시 이러한 대응관계를 나타내는 자료형이며, 키를 넣으면 그에 맞는 값을 얻을 수 있습니다. 리스트나 튜플의 요소들에 접근할 때에는 요소의 번호인 인덱스를 활용했지만, 딕셔너리에서는 키를 활용합니다. 딕셔너리의 각 요소는 키와 값을 콜론으로 대응시킨 쌍이고, 각 쌍들은 컴마로 구분합니다. 이 쌍들을 중괄호로 묶어주면 딕셔너리가 생성됩니다.

dict1의 구조를 이해하는 것은 어렵지 않을 것입니다. dict2의 구조는 약간 더 복잡합니다. “이름”이라는 문자열 키에 리스트가 값으로 대응하고, “종”이라는 문자열 키에 리스트가 값으로 대응합니다. 앞으로 계속 마주칠 DataFrame, Json에서 활용되는 구조이기 때문에, 정확히 이해하고 넘어가야 합니다. dict2를 테이블로 표현하면 다음과 같습니다. 즉 dict2는 키-값의 쌍이 하나의 컬럼을 이루는 표로 표현할 수 있습니다.

이름
펭수 펭귄
뽀로로 펭귄
뿡뿡이 NA
뚝딱이 도깨비

참고자료

Jeonghyun Gan, DataScience Lab